local extension = Package:new("shu")
extension.extensionName = "klxf"
-- extension.game_modes_whitelist = { 'kl_heg_mode' }

Fk:loadTranslationTable {
  ["shu"] = "蜀",
}
local U = require "packages/utility/utility"
local H = require "packages/klxf/util"

local liubei = General(extension, "kl__liubei", "shu", 4)
local kl__rende = fk.CreateActiveSkill {
  name = "kl__rende",
  anim_type = "support",
  min_card_num = 1,
  target_num = 1,
  prompt = "#kl__rende",
  card_filter = function(self, to_select, selected)
    return table.contains(Self:getCardIds("he"), to_select)
  end,
  target_filter = function(self, to_select, selected)
    return #selected == 0 and to_select ~= Self.id and
        Fk:currentRoom():getPlayerById(to_select):getMark("_kl__rende-phase") == 0
  end,
  on_use = function(self, room, effect)
    local target = room:getPlayerById(effect.tos[1])
    local player = room:getPlayerById(effect.from)
    local cards = effect.cards
    local marks = player:getMark("_rende_cards-phase")
    room:moveCardTo(cards, Player.Hand, target, fk.ReasonGive, self.name, nil, false)
    room:addPlayerMark(player, "_rende_cards-phase", #cards)
    room:setPlayerMark(target, "_kl__rende-phase", 1)
    if marks < 2 and marks + #cards >= 2 then
      cards = U.getUniversalCards(room, "b", true)
      local use = U.askForUseRealCard(room, player, cards, nil, self.name, "#kl__rende-ask",
        { expand_pile = cards, bypass_times = true, extraUse = true }, true, true)
      if use then
        use = {
          card = Fk:cloneCard(use.card.name),
          from = player.id,
          tos = use.tos,
        }
        use.card.skillName = self.name
        room:useCard(use)
      end
    end
  end,
  -- before_use = function(self, player, use)
  --   use.extraUse = true
  -- end,
} --bug:仁德出的杀无次数限制但计入次数
local kl__jijiang = fk.CreateTriggerSkill {
  name = "kl__jijiang",
  anim_type = "support",
  events = { fk.AfterCardsMove },
  can_trigger = function(self, event, target, player, data)
    if target == player
        and player:hasSkill(self)
        and not table.every(player.room:getOtherPlayers(player), function(p) return p.kingdom ~= player.kingdom end)
        and player.kingdom ~= "unknown"
        and player:usedSkillTimes(self.name, Player.HistoryTurn) == 0 then
      for _, move in ipairs(data) do
        if move.toArea == Card.PlayerHand then
          if move.from == player.id and move.to ~= player.id and
              not player.room:getPlayerById(move.to).dead and
              player.room:getPlayerById(move.to).kingdom == player.kingdom and
              not table.contains(player:getTableMark("kl__jijiang-turn"), move.to) then
            return true
          end
        end
      end
    end
  end,
  on_trigger = function(self, event, target, player, data)
    local room = player.room
    local targets = {}
    for _, move in ipairs(data) do
      if move.toArea == Card.PlayerHand then
        if move.from == player.id and move.to ~= player.id and
            player.room:getPlayerById(move.to).kingdom == player.kingdom and
            not table.contains(player:getTableMark("kl__jijiang-turn"), move.to) then
          table.insertIfNeed(targets, move.to)
        end
      end
    end
    room:sortPlayersByAction(targets)
    for _, id in ipairs(targets) do
      if not player:hasSkill(self) then break end
      local to = room:getPlayerById(id)
      if to and not to.dead then
        self:doCost(event, to, player, data)
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    return player.room:askForSkillInvoke(player, self.name, nil, "#kl__jijiang-invoke::" .. target.id)
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:doIndicate(player.id, { target.id })
    room:addTableMark(player, "kl__jijiang-turn", target.id)
    local use = room:askForUseCard(target, "slash", nil, "#kl__jijiang-use", true, { bypass_times = true })
    if use then
      -- use = {
      --   card = Fk:cloneCard("slash"),
      --   from = target.id,
      --   tos = use.tos,
      -- }
      -- use.card.skillName = self.name
      room:useCard(use)
    end
  end,
}
liubei:addSkill(kl__rende)
liubei:addSkill(kl__jijiang)
Fk:loadTranslationTable {
  ["kl__liubei"] = "刘备",
  ["#kl__liubei"] = "乱世的枭雄",
  ["designer:kl__liubei"] = "官方&抗绿先锋",

  ["kl__rende"] = "仁德",
  [":kl__rende"] = "出牌阶段每名角色限一次，你可将任意张手牌交给一名其他角色，每阶段你以此法给出第二张牌时，你可视为使用一张基本牌（无次数限制但计入次数）。",
  ["#kl__rende"] = "仁德：将任意张手牌交给一名角色，若此阶段交出达到两张，你可视为使用一张基本牌",
  ["#kl__rende-ask"] = "仁德：你可视为使用一张基本牌",

  ["kl__jijiang"] = "激将",
  [":kl__jijiang"] = "每回合限一次，当与你势力相同的其他角色获得你的牌后，你可令其选择是否使用一张【杀】。",
  ["#kl__jijiang-invoke"] = "激将：可令 %dest 选择是否使用一张【杀】？",
  ["#kl__jijiang-use"] = "激将：你可使用一张【杀】",

  ["$kl__rende1"] = "以德服人。",
  ["$kl__rende2"] = "施仁布泽，乃我大汉立国之本。",
  ["$kl__jijiang1"] = "蜀将何在？",
  ["$kl__jijiang2"] = "尔等敢应战否？",
  ["~kl__liubei"] = "汉室未兴，祖宗未耀，朕实不忍此时西去……",
}

local liushan = General(extension, "kl__liushan", "shu", 3)
local kl__fangquan = fk.CreateTriggerSkill {
  name = "kl__fangquan",
  anim_type = "control",
  events = { fk.EventPhaseEnd },
  can_trigger = function(self, event, target, player, data)
    if not (target == player and player:hasSkill(self) and
          player.phase == Player.Finish and
          not player:insideExtraTurn()) then
      return false
    end

    local play_ids = {}
    local has_used = false
    local logic = player.room.logic

    logic:getEventsOfScope(GameEvent.Phase, 1, function(e)
      if e.data[2] == Player.Play then
        table.insert(play_ids, { e.id, e.end_id })
      end
      return false
    end, Player.HistoryTurn)

    logic:getEventsOfScope(GameEvent.UseCard, 1, function(e)
      local in_play = false
      for _, ids in ipairs(play_ids) do
        if #ids == 2 and e.id > ids[1] and e.id < ids[2] then
          in_play = true
          break
        end
      end
      if in_play then
        local use = e.data[1]
        if use.from == player.id then
          for _, id in ipairs(TargetGroup:getRealTargets(use.tos)) do
            if id ~= player.id then
              has_used = true
              return true
            end
          end
        end
      end
    end, Player.HistoryTurn)

    return not has_used and not player:isNude()
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local discard = room:askForDiscard(player, 1, 1, false, self.name, true, ".", "#kl__fangquan-dis")
    if #discard > 0 then
      self.cost_data = discard
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:throwCard(self.cost_data, self.name, player)

    local candidates = table.map(room:getAlivePlayers(), Util.IdMapper) -- 允许选择自己
    local target = room:askForChoosePlayers(player, candidates, 1, 1, "#kl__fangquan-ask", self.name, true)
    if #target > 0 then
      room:getPlayerById(target[1]):gainAnExtraTurn(false, self.name)
    end
  end,
}
local kl__xiangle = fk.CreateViewAsSkill {
  name = "kl__xiangle",
  anim_type = "offensive",
  pattern = "slash",
  card_filter = Util.FalseFunc,
  view_as = function(self, cards)
    if #cards ~= 0 then
      return nil
    end
    local c = Fk:cloneCard("slash")
    c.skillName = self.name
    return c
  end,
  before_use = function(self, player, use)
    local room = player.room
    if use.tos then
      room:doIndicate(player.id, TargetGroup:getRealTargets(use.tos))
    end

    for _, p in ipairs(room:getOtherPlayers(player)) do
      if H.compareKingdomWith(p, player) then
        local cardResponded = room:askForResponse(p, "slash", "slash", "#kl__xiangle-ask:" .. player.id, true)
        if cardResponded then
          room:responseCard({
            from = p.id,
            card = cardResponded,
            skipDrop = true,
          })

          use.card = cardResponded
          return
        end
      end
    end

    room:setPlayerMark(player, "kl__xiangle-failed-true", 1)
    return self.name
  end,
  enabled_at_play = function(self, player)
    return player:getMark("kl__xiangle-failed-true") == 0 and --and player:usedSkillTimes(self.name, Player.HistoryTurn) == 0
        not table.every(Fk:currentRoom().alive_players, function(p)
          return p == player or H.compareKingdomWith(p, player, true)
        end) and player.kingdom ~= "unknown"
  end,
  enabled_at_response = function(self, player)
    return player:hasSkill(self)
        and
        not table.every(Fk:currentRoom().alive_players,
          function(p) return p == player or H.compareKingdomWith(p, player, true) end)
        and player.kingdom ~= "unknown"
        and player:usedSkillTimes(self.name, Player.HistoryTurn) == 0
  end,
}
local kl__xiangle__hujia = fk.CreateTriggerSkill {
  name = "#kl__xiangle__hujia",
  anim_type = "defensive",
  events = { fk.AskForCardUse, fk.AskForCardResponse },
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and
        (data.cardName == "jink" or (data.pattern and Exppattern:Parse(data.pattern):matchExp("jink|0|nosuit|none"))) and
        (data.extraData == nil or data.extraData.kl__xiangle__hujia_ask == nil) and
        H.getKingdomPlayersNum(player.room)[H.getKingdom(player)] > 1 and player.kingdom ~= "unknown" and
        player:getMark("kl__xiangle-failed-true") == 0
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    for _, p in ipairs(room:getOtherPlayers(player)) do
      if p:isAlive() and H.compareKingdomWith(p, player) then
        local cardResponded = room:askForResponse(p, "jink", "jink", "#kl__xiangle__hujia-ask:" .. player.id, true,
          { kl__xiangle__hujia_ask = true })
        if cardResponded then
          room:responseCard({
            from = p.id,
            card = cardResponded,
            skipDrop = true,
          })

          if event == fk.AskForCardUse then
            data.result = {
              from = player.id,
              card = Fk:cloneCard('jink'),
            }
            data.result.card:addSubcards(room:getSubcardsByRule(cardResponded, { Card.Processing }))
            data.result.card.skillName = self.name

            if data.eventData then
              data.result.toCard = data.eventData.toCard
              data.result.responseToEvent = data.eventData.responseToEvent
            end
          else
            data.result = Fk:cloneCard('jink')
            data.result:addSubcards(room:getSubcardsByRule(cardResponded, { Card.Processing }))
            data.result.skillName = self.name
          end
          return true
        end
      end
    end
  end,
}
liushan:addSkill(kl__xiangle)
kl__xiangle:addRelatedSkill(kl__xiangle__hujia)
liushan:addSkill(kl__fangquan)
Fk:loadTranslationTable {
  ["kl__liushan"] = "刘禅",
  ["#kl__liushan"] = "无为的真命主",
  ["designer:kl__liushan"] = "官方&抗绿先锋",

  ["kl__fangquan"] = "放权",
  [":kl__fangquan"] = "你的额定回合结束时，若你本回合未对其他角色使用过牌，你可弃置一张手牌，令一名角色获得一个额外回合。",
  ["#kl__fangquan-dis"] = "是否弃置一张手牌，令一名角色获得一个额外回合",
  ["#kl__fangquan-ask"] = "放权：选择一名角色，该角色将获得一个额外回合",

  ["kl__xiangle"] = "享乐",
  ["#kl__xiangle__hujia"] = "享乐",
  [":kl__xiangle"] = "每回合限一次，当你需要使用或打出【杀】或【闪】时，你可令与你势力相同的其他角色选择是否代替你使用或打出之。",
  ["#kl__xiangle-ask"] = "享乐：你可打出一张杀，视为 %src 使用或打出",
  ["#kl__xiangle__hujia-ask"] = "享乐：你可打出一张闪，视为 %src 使用或打出",

  ["$kl__fangquan1"] = "唉，这可如何是好啊！",
  ["$kl__fangquan2"] = "哎，你办事儿，我放心~",
  ["$kl__xiangle1"] = "我蜀汉岂无人乎！",
  ["$kl__xiangle2"] = "匡扶汉室，谁敢出战！",
  ["~kl__liushan"] = "哎，别打脸，我投降还不行吗？",
}

local liuchen = General(extension, "kl__liuchen", "shu", 4)
local kl__zhanjue = fk.CreateViewAsSkill {
  name = "kl__zhanjue",
  anim_type = "offensive",
  card_num = 0,
  min_target_num = 1,
  prompt = "#kl__zhanjue",
  card_filter = function(self, to_select, selected)
    return false
  end,
  -- target_filter = function(self, to_select, selected, selected_cards)
  --   local card = Fk:cloneCard("duel")
  --   card:addSubcards(Self:getCardIds(Player.Hand))
  --   return Self:canUseTo(card, Fk:currentRoom():getPlayerById(to_select))
  -- end,
  view_as = function(self, cards)
    local card = Fk:cloneCard("duel")
    card:addSubcards(Self:getCardIds(Player.Hand))
    return card
  end,
  after_use = function(self, player, use)
    local room = player.room
    if not player.dead then
      player:drawCards(1, "kl__zhanjue")
      room:addPlayerMark(player, "kl__zhanjue-phase", 1)
    end
    if use.damageDealt then
      for _, p in ipairs(room.alive_players) do
        if use.damageDealt[p.id] then
          p:drawCards(1, "kl__zhanjue")
          if p == player then
            room:addPlayerMark(player, "kl__zhanjue-phase", 1)
          end
        end
      end
    end
  end,
  enabled_at_play = function(self, player)
    return player:getMark("kl__zhanjue-phase") < 2 and not player:isKongcheng()
  end
}
liuchen:addSkill(kl__zhanjue)
Fk:loadTranslationTable {
  ["kl__liuchen"] = "刘谌",
  ["#kl__liuchen"] = "北地王",
  ["designer:kl__liuchen"] = "官方",

  ["kl__zhanjue"] = "战绝",
  [":kl__zhanjue"] = "出牌阶段，你可以将所有手牌当【决斗】使用，然后你和受伤的角色各摸一张牌。若你此法摸过两张或更多的牌，则本阶段〖战绝〗失效。",
  ["#kl__zhanjue"] = "战绝：你可以将所有手牌当【决斗】使用，然后你和受伤的角色各摸一张牌",

  ["$kl__zhanjue1"] = "成败在此一举，杀！",
  ["$kl__zhanjue2"] = "此刻，唯有死战，安能言降！",
  ["~kl__liuchen"] = "无言对百姓，有愧，见先祖……",
}

local huangzhong = General(extension, "kl__huangzhong", "shu", 4)
-- local liegong = fk.CreateTriggerSkill {
--   name = "kl__liegong",
--   frequency = Skill.Compulsory,
--   refresh_events = { fk.PreCardUse },
--   can_refresh = function(self, event, target, player, data)
--     return player == target and data.card.trueName == "slash" and player:hasSkill(self)
--   end,
--   on_refresh = function(self, event, target, player, data)
--     data.disresponsiveList = table.map(player.room.alive_players, Util.IdMapper)
--   end,
-- }
-- local liegong_mod = fk.CreateTargetModSkill {
--   name = "#kl__liegong_mod",
--   bypass_distances = function(self, player, skill, card)
--     return player:hasSkill(self) and card and card.trueName == "slash"
--   end,
-- }
-- local kl__yishi = fk.CreateTriggerSkill {
--   name = "kl__yishi",
--   events = { fk.DamageCaused },
--   can_trigger = function(self, event, target, player, data)
--     return target == player and player:hasSkill(self) and data.to ~= player
--   end,
--   on_cost = function(self, event, target, player, data)
--     return player.room:askForSkillInvoke(player, self.name, nil, "#kl__yishi-invoke::" .. data.to.id)
--   end,
--   on_use = function(self, event, target, player, data)
--     local room = player.room
--     room:doIndicate(player.id, { data.to.id })
--     if not data.to:isAllNude() then
--       local card = room:askForCardChosen(player, data.to, "hej", self.name)
--       room:obtainCard(player.id, card, false, fk.ReasonPrey)
--     end
--     return true
--   end
-- }
-- liegong:addRelatedSkill(liegong_mod)
-- huangzhong:addSkill(liegong)
-- huangzhong:addSkill(kl__yishi)
-- Fk:loadTranslationTable {
--   ["kl__huangzhong"] = "黄忠",
--   ["#kl__huangzhong"] = "老当益壮",
--   ["designer:kl__huangzhong"] = "官方&抗绿先锋",

--   ["kl__liegong"] = "烈弓",
--   [":kl__liegong"] = "锁定技，你使用【杀】无距离限制且不可被响应。",
--   ["kl__yishi"] = "义释",
--   [":kl__yishi"] = "当你对其他角色造成伤害时，你可防止此伤害，然后获得其区域内一张牌。",
--   ["#kl__yishi-invoke"] = "义释：你可防止对 %dest 造成的伤害，然后获得其区域内的一张牌",

--   ["$kl__liegong1"] = "百步穿杨！",
--   ["$kl__liegong2"] = "中！",
--   ["$kl__yishi1"] = "昨日释忠之恩，今吾虚射以报。",
--   ["$kl__yishi2"] = "君刀不砍头颅，吾箭只射盔缨。",
--   ["~kl__huangzhong"] = "不得不服老了……",
-- }
local cuifeng = fk.CreateViewAsSkill {
  name = "cuifeng",
  anim_type = "offensive",
  frequency = Skill.Limited,
  prompt = "#cuifeng-invoke",
  interaction = function()
    local names = {}
    for _, id in ipairs(Fk:getAllCardIds()) do
      local card = Fk:getCardById(id)
      if card.is_damage_card and card.skill.target_num == 1 and not card.is_derived and
          Self:canUse(card) and not Self:prohibitUse(card) then
        table.insertIfNeed(names, card.name)
      end
    end
    return U.CardNameBox { choices = names }
  end,
  card_filter = Util.FalseFunc,
  view_as = function(self, cards)
    local card = Fk:cloneCard(self.interaction.data)
    card.skillName = self.name
    return card
  end,
  enabled_at_play = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryGame) == 0
  end,
}
local cuifeng_targetmod = fk.CreateTargetModSkill {
  name = "#cuifeng_targetmod",
  bypass_distances = function(self, player, skill, card)
    return card and table.contains(card.skillNames, "cuifeng")
  end,
}
local cuifeng_trigger = fk.CreateTriggerSkill {
  name = "#cuifeng_trigger",
  mute = true,
  events = { fk.TurnEnd },
  can_trigger = function(self, event, target, player, data)
    if target == player and player:usedSkillTimes("cuifeng", Player.HistoryTurn) > 0 and player:hasSkill("cuifeng", true) then
      local n = 0
      player.room.logic:getEventsOfScope(GameEvent.UseCard, 1, function(e)
        local use = e.data[1]
        if use.from == player.id and table.contains(use.card.skillNames, "cuifeng") then
          if use.damageDealt then
            for _, p in ipairs(player.room:getAllPlayers()) do
              if use.damageDealt[p.id] then
                n = n + use.damageDealt[p.id]
              end
            end
          end
        end
        return false
      end, Player.HistoryTurn)
      return n ~= 1
    end
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    player:broadcastSkillInvoke("cuifeng")
    player.room:notifySkillInvoked(player, "cuifeng", "special")
    player:setSkillUseHistory("cuifeng", 0, Player.HistoryGame)
  end,
}
local dengnan = fk.CreateViewAsSkill {
  name = "dengnan",
  anim_type = "control",
  frequency = Skill.Limited,
  prompt = "#dengnan-invoke",
  interaction = function()
    local names = {}
    for _, id in ipairs(Fk:getAllCardIds()) do
      local card = Fk:getCardById(id)
      if card:isCommonTrick() and not card.is_damage_card and not card.is_derived and
          Self:canUse(card) and not Self:prohibitUse(card) then
        table.insertIfNeed(names, card.name)
      end
    end
    return U.CardNameBox { choices = names }
  end,
  card_filter = Util.FalseFunc,
  view_as = function(self, cards)
    local card = Fk:cloneCard(self.interaction.data)
    card.skillName = self.name
    return card
  end,
  enabled_at_play = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryGame) == 0
  end,
}
local dengnan_trigger = fk.CreateTriggerSkill {
  name = "#dengnan_trigger",
  mute = true,
  events = { fk.TurnEnd },
  can_trigger = function(self, event, target, player, data)
    if target == player and player:usedSkillTimes("dengnan", Player.HistoryTurn) > 0 and player:hasSkill("dengnan", true) then
      local mark = player:getMark("dengnan-turn")
      if mark == 0 then mark = {} end
      player.room.logic:getEventsOfScope(GameEvent.ChangeHp, 999, function(e)
        local damage = e.data[5]
        if damage then
          table.removeOne(mark, damage.to.id)
        end
      end, Player.HistoryTurn)
      return #mark == 0
    end
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    player:broadcastSkillInvoke("dengnan")
    player.room:notifySkillInvoked(player, "dengnan", "special")
    player:setSkillUseHistory("dengnan", 0, Player.HistoryGame)
  end,

  refresh_events = { fk.TargetSpecified },
  can_refresh = function(self, event, target, player, data)
    return target == player and table.contains(data.card.skillNames, "dengnan")
  end,
  on_refresh = function(self, event, target, player, data)
    local room = player.room
    room:setPlayerMark(player, "dengnan-turn", TargetGroup:getRealTargets(data.tos))
    for _, id in ipairs(TargetGroup:getRealTargets(data.tos)) do
      local p = room:getPlayerById(id)
      room:setPlayerMark(p, "@@dengnan-turn", 1)
    end
  end,
}
cuifeng:addRelatedSkill(cuifeng_targetmod)
cuifeng:addRelatedSkill(cuifeng_trigger)
dengnan:addRelatedSkill(dengnan_trigger)
huangzhong:addSkill(cuifeng)
huangzhong:addSkill(dengnan)
Fk:loadTranslationTable {
  ["kl__huangzhong"] = "黄忠",
  ["#kl__huangzhong"] = "定军之英",
  ["cuifeng"] = "摧锋",
  [":cuifeng"] = "限定技，出牌阶段，你可以视为使用一张唯一目标的伤害类牌（无距离限制），若此牌未造成伤害或造成的伤害数大于1，此回合结束时重置〖摧锋〗。",
  ["dengnan"] = "登难",
  [":dengnan"] = "限定技，出牌阶段，你可以视为使用一张非伤害类普通锦囊牌，此回合结束时，若此牌的目标均于此回合受到过伤害，你重置〖登难〗。",
  ["#cuifeng-invoke"] = "摧锋：视为使用一种伤害牌！若没造成伤害或造成伤害大于1则回合结束时重置！",
  ["#cuifeng_trigger"] = "摧锋",
  ["#dengnan-invoke"] = "登难：视为使用一种非伤害普通锦囊牌！若目标本回合均受到伤害则回合结束时重置！",
  ["@@dengnan-turn"] = "登难",
  ["#dengnan_trigger"] = "登难",
}

local machao = General(extension, "kl__machao", "shu", 4)
local kl__zhuiming = fk.CreateTriggerSkill {
  name = "kl__zhuiming",
  anim_type = "offensive",
  events = { fk.TargetSpecified },
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and data.card.trueName == "slash" and
        #AimGroup:getAllTargets(data.tos) == 1 and
        not player.room:getPlayerById(AimGroup:getAllTargets(data.tos)[1]):isNude()
  end,
  on_cost = function(self, event, target, player, data)
    self.cost_data = player.room:askForChoice(player, { "red", "black", "Cancel" }, self.name,
      "#kl__zhuiming-invoke::" .. AimGroup:getAllTargets(data.tos)[1])
    return self.cost_data ~= "Cancel"
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local to = room:getPlayerById(AimGroup:getAllTargets(data.tos)[1])
    room:doIndicate(player.id, { to.id })
    room:sendLog {
      type = "#kl__zhuiming",
      from = player.id,
      arg = self.cost_data,
      toast = true,
    }
    room:askForDiscard(to, 0, 999, true, self.name, true, nil, "#kl__zhuiming-discard:" ..
      player.id .. "::" .. self.cost_data, false)
    if player.dead or to.dead or to:isNude() then return end
    local id = room:askForCardChosen(player, to, "he", self.name)
    to:showCards({ id })
    if Fk:getCardById(id):getColorString() == self.cost_data then
      player:addCardUseHistory("slash", -1)
      data.disresponsiveList = data.disresponsiveList or {}
      table.insert(data.disresponsiveList, to.id)
      data.additionalDamage = (data.additionalDamage or 0) + 1
    end
  end,
}
local kl__mashu = fk.CreateDistanceSkill {
  name = "kl__mashu",
  frequency = Skill.Compulsory,
  correct_func = function(self, from, to)
    if from:hasSkill(self) then
      return -1
    end
  end,
}
machao:addSkill(kl__zhuiming)
machao:addSkill(kl__mashu)
Fk:loadTranslationTable {
  ["kl__machao"] = "马超",
  ["#kl__machao"] = "潼关之勇",
  ["designer:kl__machao"] = "官方",

  ["kl__mashu"] = "马术",
  [":kl__mashu"] = "锁定技，你至其他角色的距离-1。",
  ["kl__zhuiming"] = "追命",
  [":kl__zhuiming"] = "当你使用【杀】指定唯一目标后，你可声明一种颜色并令目标弃置任意张牌，然后你展示目标一张牌，若此牌颜色与你声明的颜色相同，" ..
      "则此【杀】不计入次数限制、不可被响应且伤害+1。",
  ["#kl__zhuiming-invoke"] = "追命：你可对 %dest 发动\"追命\"声明一种颜色",
  ["#kl__zhuiming"] = "%from 声明 %arg",
  ["#kl__zhuiming-discard"] = "追命：%src 声明%arg，你可弃置任意张牌",

  ["$kl__zhuiming1"] = "目标敌阵，全军突击！",
  ["$kl__zhuiming2"] = "敌人阵型已乱，随我杀！",
  ["~kl__machao"] = "请将我，葬在西凉……",
}

local zhugezhan = General(extension, "kl__zhugezhan", "shu", 4)
local kl__zuilun = fk.CreateTriggerSkill {
  name = "kl__zuilun",
  anim_type = "control",
  events = { fk.EventPhaseStart },
  can_trigger = function(self, event, target, player, data)
    return target == player and target:hasSkill(self) and player.phase == Player.Finish
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local n = 0
    if #room.logic:getActualDamageEvents(1, function(e)
          return e.data[1].from == player
        end, Player.HistoryTurn) > 0 then
      n = n + 1
    end
    local events = room.logic:getEventsOfScope(GameEvent.MoveCards, 1, function(e)
      for _, move in ipairs(e.data) do
        if move.from == player.id and move.moveReason == fk.ReasonDiscard and table.find(move.moveInfo, function(info)
              return info.fromArea == Card.PlayerHand or info.fromArea == Card.PlayerEquip
            end) then
          return true
        end
      end
    end, Player.HistoryTurn)
    if #events == 0 then
      n = n + 1
    end
    if table.every(room.alive_players, function(p) return p:getHandcardNum() >= player:getHandcardNum() end) then
      n = n + 1
    end
    if room:askForSkillInvoke(player, self.name, nil, "#kl__zuilun-invoke:::" .. tostring(n)) then
      self.cost_data = n
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local n = self.cost_data
    local cards = room:getNCards(3)
    local result = room:askForGuanxing(player, cards, { 3 - n, 3 }, { n, n }, self.name, true, { "Top", "toObtain" })
    if #result.top > 0 then
      for i = #result.top, 1, -1 do
        table.removeOne(room.draw_pile, result.top[i])
        table.insert(room.draw_pile, 1, result.top[i])
      end
    end
    if #result.bottom > 0 then
      room:moveCardTo(result.bottom, Player.Hand, player, fk.ReasonJustMove, self.name, "", false, player.id)
    else
      local targets = table.map(room:getOtherPlayers(player, false), Util.IdMapper)
      if #targets == 0 then return false end
      local to = room:getPlayerById(room:askForChoosePlayers(player, targets, 1, 1, "#kl__zuilun-choose", self.name,
        false)[1])
      room:loseHp(player, 1, self.name)
      if not to.dead then
        room:loseHp(to, 1, self.name)
      end
    end
  end,
}
zhugezhan:addSkill(kl__zuilun)
Fk:loadTranslationTable {
  ["kl__zhugezhan"] = "诸葛瞻",
  ["#kl__zhugezhan"] = "临难死义",
  ["designer:kl__zhugezhan"] = "官方&抗绿先锋",

  ["kl__zuilun"] = "罪论",
  [":kl__zuilun"] = "结束阶段，你可观看牌堆顶三张牌，你每满足以下一项便获得其中的一张，然后以任意顺序放回其余的牌：1.你于此回合内造成过伤害；" ..
      "2.你于此回合内未弃置过牌；3.手牌数为全场最少。若均不满足，你与一名其他角色失去1点体力。",
  ["#kl__zuilun-invoke"] = "是否发动 罪论，观看牌堆顶3张牌，保留%arg张，放回其余的牌",
  ["#kl__zuilun-choose"] = "罪论：选择一名其他角色，你与其各失去1点体力",

  ["$kl__zuilun1"] = "吾有三罪，未能除黄皓、制伯约、守国土。",
  ["$kl__zuilun2"] = "唉，数罪当论，吾愧对先帝恩惠。",
  ["~kl__zhugezhan"] = "临难而死义，无愧先父。",
}

local xushu = General(extension, "kl__xushu", "shu", 3)
local kl__bianzhen = fk.CreateTriggerSkill {
  name = "kl__bianzhen",
  anim_type = "control",
  events = { fk.EventPhaseEnd },
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and player.phase == Player.Finish and not player:isNude()
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local tos, card = room:askForChooseCardAndPlayers(player, table.map(room.alive_players, Util.IdMapper), 1, 1, ".",
      "#kl__bianzhen-choose", self.name, true)
    if #tos == 0 or not card then return false end
    -- 选择阶段类型（包含全部6个阶段）
    local phases = { "start", "judge", "draw", "play", "discard", "finish" }
    local choice = room:askForChoice(player, phases, self.name, "#kl__bianzhen-phase", false)
    if not choice then return false end
    self.cost_data = {
      target = tos[1],
      card = card,
      phase = ({
        ["start"] = Player.Start,
        ["judge"] = Player.Judge,
        ["draw"] = Player.Draw,
        ["play"] = Player.Play,
        ["discard"] = Player.Discard,
        ["finish"] = Player.Finish
      })[choice]
    }
    return true
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local targetPlayer = room:getPlayerById(self.cost_data.target)
    room:throwCard(self.cost_data.card, self.name, player, player)
    -- 赋予仅包含指定阶段的额外回合
    targetPlayer:gainAnExtraTurn(true, self.name, {
      phase_table = { self.cost_data.phase }
    })
    table.removeOne(targetPlayer.phases, Player.Draw)
    local discardIndex = table.indexOf(targetPlayer.phases, Player.Discard)
    if discardIndex then
      table.insert(targetPlayer.phases, discardIndex + 1, Player.Draw)
    end
  end,
}
local kl__jujian = fk.CreateTriggerSkill {
  name = "kl__jujian",
  anim_type = "defensive",
  events = { fk.DamageInflicted },
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and H.compareKingdomWith(player, data.to) and data.damage >= data.to.hp
  end,
  on_cost = function(self, event, target, player, data)
    return player.room:askForSkillInvoke(player, self.name, nil, "#kl__jujian-ask")
  end,
  interaction = function(self)
    return UI.ComboBox {
      choices = { "mainGeneral", "deputyGeneral" },
    }
  end,
  on_use = function(self, event, target, player, data)
    data.damage = 0
    local room = player.room
    H.transformGeneral(room, player, true, false, 3)
  end,
}
xushu:addSkill(kl__bianzhen)
xushu:addSkill(kl__jujian)
Fk:loadTranslationTable {
  ["kl__xushu"] = "徐庶",
  ["#kl__xushu"] = "身曹心汉",
  ["designer:kl__xushu"] = "3d吧&抗绿先锋",

  ["kl__bianzhen"] = "变阵",
  [":kl__bianzhen"] = "额定回合结束时，你可弃置一张牌，令一名角色执行一个仅包含一个阶段的额外回合。",
  ["#kl__bianzhen-choose"] = "变阵：选择要赋予额外回合的角色",
  ["#kl__bianzhen-phase"] = "变阵：请选择要声明的阶段类型",

  ["start"] = "准备阶段",
  ["judge"] = "判定阶段",
  ["draw"] = "摸牌阶段",
  ["play"] = "出牌阶段",
  ["discard"] = "弃牌阶段",
  ["finish"] = "结束阶段",

  ["kl__jujian"] = "举荐",
  [":kl__jujian"] = "当与你势力相同的角色受到伤害时，若伤害值不小于其体力值，你可防止之，然后你变更此武将牌。",
  ["#kl__jujian-ask"] = "举荐：是否防止此伤害，然后你变更此武将牌",

  ["$kl__jujian1"] = "天下大任，望君莫辞！",
  ["$kl__jujian2"] = "卧龙之才，远胜于我。",
  ["$kl__bianzhen1"] = "既遇明主，天下可图！",
  ["$kl__bianzhen2"] = "弃武从文，安邦卫国！",
  ["~kl__xushu"] = "大义无言，虽死无怨。",
}

local liyan = General(extension, "kl__liyan", "shu", 3)
local kl__fulin = fk.CreateTriggerSkill {
  name = "kl__fulin",
  frequency = Skill.Compulsory,
  events = { fk.TargetConfirming },
  can_trigger = function(self, event, target, player, data)
    if not player:hasSkill(self) then return false end
    local card = data.card
    local source = player.room:getPlayerById(data.from)
    return target == player and source ~= player and card.type == Card.TypeBasic
        and #source:getCardIds(Player.Hand) <= #player:getCardIds(Player.Hand)
  end,
  on_use = function(self, event, target, player, data)
    AimGroup:cancelTarget(data, player.id)
    return true
  end,
}
local kl__duliang = fk.CreateTriggerSkill {
  name = "kl__duliang",
  events = { fk.EventPhaseStart },
  can_trigger = function(self, event, target, player, data)
    return target.phase == Player.Start and
        player.kingdom == target.kingdom and
        player:hasSkill(self.name) and
        not player.dead and
        not target.dead
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    if room:askForSkillInvoke(player, self.name, data, "#kl__duliang-ask::" .. target.id) then
      self.cost_data = target
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:drawCards(player, 1, self.name)
    if player == target then
      -- 调整阶段顺序
      local targetPlayer = self.cost_data
      table.removeOne(targetPlayer.phases, Player.Draw)
      local discardIndex = table.indexOf(targetPlayer.phases, Player.Discard)
      if discardIndex then
        table.insert(targetPlayer.phases, discardIndex + 1, Player.Draw)
      end
    else
      -- 使用askForCard实现多选
      local toGive = room:askForCard(player, 1, 2, true, self.name, true, ".",
        "#kl__duliang-give::" .. target.id)
      if #toGive > 0 then
        room:moveCardTo(toGive, Card.PlayerHand, target, fk.ReasonGive, self.name)
      end
      -- 调整阶段顺序
      local targetPlayer = self.cost_data
      table.removeOne(targetPlayer.phases, Player.Draw)
      local discardIndex = table.indexOf(targetPlayer.phases, Player.Discard)
      if discardIndex then
        table.insert(targetPlayer.phases, discardIndex + 1, Player.Draw)
      end
    end
  end,
}
liyan:addSkill(kl__fulin)
liyan:addSkill(kl__duliang)
Fk:loadTranslationTable {
  ["kl__liyan"] = "李严",
  ["#kl__liyan"] = "矜风流务",
  ["designer:kl__liyan"] = "3d吧&抗绿先锋",

  ["kl__fulin"] = "腹鳞",
  [":kl__fulin"] = "锁定技，当你成为其他角色使用基本牌的目标时，若其手牌数不大于你，取消之。",
  ["kl__duliang"] = "督粮",
  [":kl__duliang"] = "每名与你势力相同的角色准备阶段，你可摸一张牌，然后交给其至多两张牌。若如此做，其本回合的摸牌阶段移至弃牌阶段后执行。",
  ["#kl__duliang-ask"] = "督粮：是否发动\"督粮\"摸一张牌并交给 %dest 至多两张牌？",
  ["#kl__duliang-give"] = "督粮：选择至多两张牌交给 %dest 的牌，或者点取消不给",

  ["$kl__duliang1"] = "粮草已到，请将军验看。",
  ["$kl__duliang2"] = "告诉丞相，山路难走！请宽限几天。",
  ["$kl__fulin1"] = "丞相，丞相！你们没看见我吗？",
  ["$kl__fulin2"] = "我乃托孤重臣，却在这儿搞什么粮草！",
  ["~kl__liyan"] = "孔明这一走，我算是没指望了。",
}

-- local xujing = General(extension, "kl__xujing", "shu", 3)
-- local kl__xuyu = fk.CreateTriggerSkill {
--   name = "kl__xuyu",
--   anim_type = "support",
--   frequency = Skill.Compulsory,
--   events = { fk.CardUseFinished },
--   can_trigger = function(self, event, target, player, data)
--     if target == player and player:hasSkill(self) then
--       local events = player.room.logic:getEventsOfScope(GameEvent.UseCard, 2, function(e)
--         local use = e.data[1]
--         return use.from == target.id
--       end, Player.HistoryTurn)
--       return #events == 1 and events[1].data[1] == data or #events == 2 and events[2].data[1] == data
--     end
--   end,
--   on_use = function(self, event, target, player, data)
--     local room = player.room
--     if player:usedSkillTimes(self.name, Player.HistoryTurn) % 2 == 1 then
--       room:drawCards(player, 1, self.name)
--     elseif player:getHandcardNum() > 0 then
--       room:askForDiscard(player, 1, 1, true, self.name, false)
--     end
--   end
-- } --
-- local kl__shijian = fk.CreateTriggerSkill {
--   name = "kl__shijian",
--   anim_type = "support",
--   events = { fk.CardUseFinished },
--   can_trigger = function(self, event, target, player, data)
--     if target ~= player and player:hasSkill(self) and target.phase ~= Player.NotActive and not player:isNude() then
--       local events = player.room.logic:getEventsOfScope(GameEvent.UseCard, 4, function(e)
--         local use = e.data[1]
--         return use.from == target.id
--       end, Player.HistoryTurn)
--       return #events == 3 and events[3].data[1] == data or #events == 4 and events[4].data[1] == data
--     end
--   end,
--   on_use = function(self, event, target, player, data)
--     local room = player.room
--     if #events == 3 and events[3].data[1] == data then
--       local toGive = room:askForCard(player, 1, 1, true, self.name, true, ".",
--         "#kl__shijian-give::")
--       if #toGive > 0 then
--         room:moveCardTo(toGive, Card.PlayerHand, target, fk.ReasonGive, self.name)
--         room:setPlayerMark(target, "@kl__shijian-turn", 1)
--       end
--     elseif target:getMark("@kl__shijian-turn") > 0 then
--       room:drawCards(player, 1, self.name)
--       room:drawCards(target, 1, self.name)
--     end
--   end,
-- }
-- local kl__shijian__4 = fk.CreateTriggerSkill {
--   name = "#kl__shijian__4",
--   anim_type = "support",
--   frequency = Skill.Compulsory,
--   events = { fk.CardUseFinished },
--   can_trigger = function(self, event, target, player, data)
--     if target == player and player:hasSkill(self) then
--       local events = player.room.logic:getEventsOfScope(GameEvent.UseCard, 4, function(e)
--         local use = e.data[1]
--         return use.from == target.id
--       end, Player.HistoryTurn)
--       return #events == 4 and events[4].data[1] == data
--     end
--   end,
--   on_use = function(self, event, target, player, data)
--     local room = player.room
--     local targets = { player:getMark("kl__shijian__4-turn") }
--     room:drawCards(player, 1, self.name)
--     room:drawCards(targets, 1, self.name)
--   end,
-- } --bug:使用第四张牌会出报错
-- -- 04/11 20:03:09 Main[C] ./lua/core\room\card_manager.lua:81: assertion failed!
-- -- stack traceback:
-- -- [C]: in function 'assert'
-- -- ./lua/core\room\card_manager.lua:81: in function 'core.room.card_manager.getCardsByArea'
-- -- ./lua/core\room\card_manager.lua:108: in function 'core.room.card_manager.applyMoveInfo'
-- -- lua/client/client.lua:160: in method 'moveCards'
-- -- lua/client/client.lua:780: in local 'cb'
-- -- lua/client/client.lua:66: in function 'ClientCallback'
-- -- 04/11 20:03:09 Room[C] ./lua/core\room\card_manager.lua:81: assertion failed!
-- -- stack traceback:
-- -- [C]: in function 'assert'
-- -- ./lua/core\room\card_manager.lua:81: in function 'core.room.card_manager.getCardsByArea'
-- -- ./lua/core\room\card_manager.lua:108: in function 'core.room.card_manager.applyMoveInfo'
-- -- ./lua/server\events\movecard.lua:117: in function <./lua/server\events\movecard.lua:15>
-- -- (...tail calls...)
-- -- 04/11 20:03:49 Main[W] Retrying to obtain clipboard.
-- xujing:addSkill(kl__xuyu)
-- xujing:addSkill(kl__shijian)
-- Fk:loadTranslationTable {
--   ["kl__xujing"] = "许靖",
--   ["#kl__xujing"] = "品评名士",
--   ["designer:kl__xujing"] = "官方&抗绿先锋",

--   ["kl__xuyu"] = "虚誉",
--   [":kl__xuyu"] = "锁定技，当你于一回合内使用第一/二张牌后，你摸/弃一张牌。",
--   ["kl__shijian"] = "实荐",
--   [":kl__shijian"] = "当其他角色于其回合内使用第三张牌后，你可交给其一张牌。若如此做，本回合其使用第四张牌后，其与你各摸一张牌。",

--   ["@kl__shijian-turn"] = "实荐",
--   ["#kl__shijian-give::"] = "实荐：你可交给其一张牌。若如此做，本回合其使用第四张牌后，其与你各摸一张牌。",

--   ["$kl__xuyu1"] = "誉名浮虚，播流四海。",
--   ["$kl__xuyu2"] = "誉虚之名，得保一时。",
--   ["$kl__shijian1"] = "国家安危，在于足下。",
--   ["$kl__shijian2"] = "行之得道，即社稷用宁。",
--   ["~kl__xujing"] = "漂薄风波，绝粮茹草……",
-- }

local huojun = General(extension, "kl__huojun", "shu", 4)
local kl__gue = fk.CreateViewAsSkill {
  name = "kl__gue",
  anim_type = "defensive",
  pattern = "slash,jink",
  prompt = "#kl__gue",
  interaction = function()
    local names = {}
    for _, name in ipairs({ "slash", "jink" }) do
      local card = Fk:cloneCard(name)
      if (Fk.currentResponsePattern == nil and Self:canUse(card)) or
          (Fk.currentResponsePattern and Exppattern:Parse(Fk.currentResponsePattern):match(card)) then
        table.insertIfNeed(names, card.name)
      end
    end
    if #names == 0 then return end
    return U.CardNameBox { choices = names }
  end,
  card_filter = Util.FalseFunc,
  view_as = function(self, cards)
    if not self.interaction.data then return end
    local card = Fk:cloneCard(self.interaction.data)
    card.skillName = self.name
    return card
  end,

  before_use = function(self, player, use)
    local room = player.room
    local handNum = player:getHandcardNum()

    if use.tos then
      room:doIndicate(player.id, TargetGroup:getRealTargets(use.tos))
    end

    if handNum == 1 then return end

    if handNum > 1 then
      room:askForDiscard(player, handNum - 1, handNum - 1, false, self.name, false)
      room:setPlayerMark(player, "kl__gue-failed-turn", 1)
    else
      player:drawCards(1 - handNum, self.name)
      room:setPlayerMark(player, "kl__gue-failed-turn", 1)
    end
  end,
  enabled_at_play = function(self, player)
    return
        player:getHandcardNum() ~= 1
  end,
  enabled_at_response = function(self, player, res)
    return
        player:getHandcardNum() ~= 1
  end,
}
huojun:addSkill(kl__gue)
Fk:loadTranslationTable {
  ["kl__huojun"] = "霍峻",
  ["#kl__huojun"] = "坚磐石锐",
  ["designer:kl__huojun"] = "官方&抗绿先锋",

  ["kl__gue"] = "孤扼",
  [":kl__gue"] = "当你需要使用或打出【杀】或【闪】时，若你的手牌数不为一，则你可调整至一，视为你使用或打出之。",
  ["#kl__gue"] = "是否调整手牌至一，视为使用 %arg？",

  ["$kl__gue1"] = "哀兵必胜，况吾众志成城。",
  ["$kl__gue2"] = "扼守孤城，试问万夫谁开？",
  ["~kl__huojun"] = "蒙君知恩，奈何早薨……",
}

local feiyi = General(extension, "kl__feiyi", "shu", 3)
local kl__shengxi = fk.CreateTriggerSkill {
  name = "kl__shengxi",
  anim_type = "drawcard",
  events = { fk.EventPhaseStart },
  can_trigger = function(self, event, target, player, data)
    return player == target and player:hasSkill(self) and player.phase == Player.Finish and
        #player.room.logic:getActualDamageEvents(1, function(e) return e.data[1].from == player end) == 0
  end,
  on_use = function(self, event, target, player, data)
    player:drawCards(2, self.name)
  end,
}
local kl__shoucheng = fk.CreateTriggerSkill {
  name = "kl__shoucheng",
  anim_type = "support",
  events = { fk.AfterCardsMove },
  can_trigger = function(self, event, target, player, data)
    if not player:hasSkill(self) or player:getMark("kl__shoucheng_used-turn") > 0 then return end
    for _, move in ipairs(data) do
      if move.from then
        local from = player.room:getPlayerById(move.from)
        if from:isKongcheng() and H.compareKingdomWith(from, player) and from.phase == Player.NotActive then
          for _, info in ipairs(move.moveInfo) do
            if info.fromArea == Card.PlayerHand then
              return true
            end
          end
        end
      end
    end
  end,
  on_trigger = function(self, event, target, player, data)
    local targets = {}
    local room = player.room
    for _, move in ipairs(data) do
      if move.from then
        local from = room:getPlayerById(move.from)
        if from:isKongcheng() and H.compareKingdomWith(from, player) and from.phase == Player.NotActive then
          for _, info in ipairs(move.moveInfo) do
            if info.fromArea == Card.PlayerHand then
              if not table.contains(targets, from.id) then
                table.insert(targets, from.id)
              end
            end
          end
        end
      end
    end
    room:sortPlayersByAction(targets)
    for _, p in ipairs(targets) do
      local to = room:getPlayerById(p)
      if to.dead or not player:hasSkill(self) then break end
      self:doCost(event, to, player, nil)
    end
  end,
  on_cost = function(self, event, target, player, data)
    return player.room:askForSkillInvoke(player, self.name, nil, "#kl__shoucheng-draw::" .. target.id)
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:addPlayerMark(player, "kl__shoucheng_used-turn", 1)
    room:doIndicate(player.id, { target.id })
    target:drawCards(2, self.name)
  end,
}
feiyi:addSkill(kl__shoucheng)
feiyi:addSkill(kl__shengxi)
Fk:loadTranslationTable {
  ["kl__feiyi"] = "费祎",
  ["#kl__feiyi"] = "中才之相",
  ["designer:kl__feiyi"] = "官方&抗绿先锋",

  ["kl__shengxi"] = "生息",
  [":kl__shengxi"] = "结束阶段，若你本回合未造成过伤害，你可摸两张牌。",
  ["kl__shoucheng"] = "守成",
  [":kl__shoucheng"] = "每回合限一次，与你势力相同的角色于其回合外失去手牌后，若其没有手牌，你可令其摸两张牌。",
  ["#kl__shoucheng-draw"] = "守成：你可令 %dest 摸两张牌",

  ["$kl__shengxi1"] = "国之生计，在民生息。",
  ["$kl__shengxi2"] = "安民止战，兴汉室！",
  ["$kl__shoucheng1"] = "待吾等助将军一臂之力！",
  ["$kl__shoucheng2"] = "国库盈余，可助军威。",
  ["~kl__feiyi"] = "今为小人所伤，皆酒醉之误……",
}

local jiangwei = General(extension, "kl__jiangwei", "shu", 4)
local kl__tiaoxin = fk.CreateActiveSkill {
  name = "kl__tiaoxin",
  anim_type = "control",
  card_num = 0,
  min_target_num = 1,
  prompt = "#kl__tiaoxin",
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryTurn) == 0
  end,
  card_filter = Util.FalseFunc,
  target_filter = function(self, to_select, selected)
    local target = Fk:currentRoom():getPlayerById(to_select)
    return target:inMyAttackRange(Self) and not table.contains(selected, to_select)
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    for _, id in ipairs(effect.tos) do
      if player.dead then break end
      local target = room:getPlayerById(id)
      if target.dead then goto continue end

      -- 强制指定目标为技能使用者
      local use = room:askForUseCard(target, "slash", "slash", "#tiaoxin-use", true,
        { exclusive_targets = { player.id } })
      if use then
        room:useCard(use) -- 手动执行卡牌使用
      else
        if not target:isNude() then
          local card = room:askForCardChosen(player, target, "he", self.name)
          room:throwCard({ card }, self.name, target, player)
        end
      end
      ::continue::
    end
  end
}
local kl__guanxing = fk.CreateTriggerSkill {
  name = "kl__guanxing",
  anim_type = "control",
  events = { fk.EventPhaseStart },
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and
        player.phase == Player.Start
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:askForGuanxing(player, room:getNCards(7), { 0, #room.alive_players }) --#room.alive_players
  end,
}
local kl__zhiji = fk.CreateTriggerSkill {
  name = "kl__zhiji",
  events = { fk.EventPhaseStart },
  frequency = Skill.Compulsory, -- 添加锁定技标识
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and
        player.phase == Player.Start and
        (player:getHandcardNum() == math.min(table.unpack(table.map(player.room:getAlivePlayers(), function(p)
            return p
                :getHandcardNum()
          end)))
          or table.every(player.room.alive_players, function(p) return p.hp >= player.hp end))
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:handleAddLoseSkills(player, "kl__guanxing")
    room.logic:getCurrentEvent():findParent(GameEvent.Turn):addCleaner(function()
      room:handleAddLoseSkills(player, "-kl__guanxing", nil, true, false)
    end)
  end,
}
jiangwei:addSkill(kl__tiaoxin)
jiangwei:addSkill(kl__zhiji)
jiangwei:addRelatedSkill(kl__guanxing)
Fk:loadTranslationTable {
  ["kl__jiangwei"] = "姜维",
  ["#kl__jiangwei"] = "龙的衣钵",
  ["designer:kl__jiangwei"] = "官方&抗绿先锋",

  ["kl__tiaoxin"] = "挑衅",
  [":kl__tiaoxin"] = "出牌阶段限一次，你可选择任意名你在其攻击范围内的角色，这些角色需对你使用一张【杀】，否则你弃置其一张牌。",
  ["#kl__tiaoxin-use"] = "挑衅：对其使用一张【杀】，否则其弃置你一张牌",
  ["#kl__tiaoxin"] = "挑衅：选择任意名你在其攻击范围内的角色，这些角色需对你使用一张【杀】，否则你弃置其一张牌",
  ["kl__zhiji"] = "志继",
  [":kl__zhiji"] = "锁定技，准备阶段，若你的手牌数或体力值为全场最少，你本回合获得〖观星〗。",

  ["kl__guanxing"] = "观星",
  [":kl__guanxing"] = "准备阶段，你可观看牌堆顶七张牌，将其中至多X张牌置于牌堆顶，其余置于牌堆底（X为角色数）。",


  ["$kl__tiaoxin1"] = "小小娃娃，乳臭未干。",
  ["$kl__tiaoxin2"] = "快滚回去，叫你主将出来！",
  ["$kl__guanxing_kl__jiangwei1"] = "继丞相之遗志，讨篡汉之逆贼！",
  ["$kl__guanxing_kl__jiangwei2"] = "克复中原，指日可待！",
  ["~kl__jiangwei"] = "臣等正欲死战，陛下何故先降？",
}

local zhangyi = General(extension, "kl__zhangyi", "shu", 4)
local kl__dianjun = fk.CreateTriggerSkill {
  name = "kl__dianjun",
  anim_type = "offensive",
  frequency = Skill.Compulsory,
  events = { fk.EventPhaseEnd },
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and player.phase == Player.Finish
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    -- room:damage {
    --   from = player,
    --   to = player,
    --   damage = 1,
    --   skillName = self.name,
    -- }
    player:drawCards(2, self.name)
    room:damage {
      damage = 1,
      damageType = fk.NormalDamage,
      to = player,
      skillName = self.name,
    }
    -- player.room:loseHp(player, 1, self.name)
    if player.dead then return false end
    player:gainAnExtraPhase(Player.Play)
  end,
}
local kl__kangrui = fk.CreateTriggerSkill {
  name = "kl__kangrui",
  anim_type = "support",
  events = { fk.Damaged, fk.EventPhaseStart },
  can_trigger = function(self, event, target, player, data)
    if event == fk.EventPhaseStart then
      -- 回合开始时清除标记
      if target.phase == Player.Start then
        target.room:setPlayerMark(target, "kangrui_used-turn", 0)
      end
      return false
    end

    -- 检查势力相同且是本回合第一次受伤
    return target:getMark("kangrui_used-turn") == 0 and
        H.compareKingdomWith(target, player) and
        target.room:getCurrent() == target and
        player:hasSkill(self.name)
  end,
  on_cost = function(self, event, target, player, data)
    -- 由受伤角色自己选择是否发动
    local room = target.room
    if room:askForSkillInvoke(target, self.name, data, "#kl__kangrui-invoke") then
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = target.room
    room:addPlayerMark(target, "kangrui_used-turn", 1)

    -- 先选择要使用的牌
    local card = room:askForCard(target, 1, 1, true, self.name, true, ".", "#kl__kangrui-choose-card")
    if not card then return end

    -- 再选择要视为的卡牌类型
    local choice = room:askForChoice(target, { "peach", "analeptic" }, self.name, "#kl__kangrui-choose-type")

    -- 创建虚拟卡牌
    local c = Fk:cloneCard(choice)
    c.skillName = self.name
    c:addSubcard(card[1])

    -- 使用卡牌
    local use = {
      card = c,
      from = target.id,
      tos = target:isWounded() and { { target.id } } or nil,
    }
    room:useCard(use)
  end
} --依次法使用的【酒】无次数限制
zhangyi:addSkill(kl__dianjun)
zhangyi:addSkill(kl__kangrui)
Fk:loadTranslationTable {
  ["kl__zhangyi"] = "张翼",
  ["#kl__zhangyi"] = "奉公弗怠",
  ["designer:kl__zhangyi"] = "官方&抗绿先锋",

  ["kl__dianjun"] = "殿军",
  [":kl__dianjun"] = "锁定技，回合结束时，你摸两张牌,受到1点伤害，然后执行一个额外的出牌阶段。",
  ["kl__kangrui"] = "亢锐",
  [":kl__kangrui"] = "当一名与你势力相同的角色于其回合内首次受到伤害后，其可将一张牌当【桃】或【酒】使用。",
  ["#kl__kangrui-invoke"] = "亢锐：是否将一张牌当【桃】或【酒】使用？",
  ["#kl__kangrui-choose-card"] = "亢锐：请选择要使用的牌",
  ["#kl__kangrui-choose-type"] = "亢锐：请选择要视为的卡牌类型",

  ["$kl__dianjun1"] = "大将军勿忧，翼可领后军。",
  ["$kl__dianjun2"] = "诸将速行，某自领军殿后！",
  ["$kl__kangrui1"] = "尔等魍魉，愿试吾剑之利乎？",
  ["$kl__kangrui2"] = "诸君鼓力，克复中原指日可待！",
  ["~kl__zhangyi"] = "伯约不见疲惫之国力乎？",
}

local zhangsong = General(extension, "kl__zhangsong", "shu", 3)
local kl__qiangzhi = fk.CreateTriggerSkill {
  name = "kl__qiangzhi",
  mute = true,
  events = { fk.EventPhaseStart },
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and player.phase == Player.Play and
        table.find(player.room:getOtherPlayers(player), function(p) return p:getHandcardNum() > 0 end)
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local targets = table.map(table.filter(room:getOtherPlayers(player), function(p)
      return not p:isKongcheng()
    end), Util.IdMapper)
    local to = room:askForChoosePlayers(player, targets, 1, 1, "#kl__qiangzhi-choose", self.name, true)
    if #to > 0 then
      self.cost_data = to[1]
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    player:broadcastSkillInvoke(self.name, 1)
    room:notifySkillInvoked(player, self.name, "control")
    local to = room:getPlayerById(self.cost_data)
    room:doIndicate(player.id, { self.cost_data })
    local card = Fk:getCardById(room:askForCardChosen(player, to, "h", self.name))
    to:showCards(card)
    local cardType = card:getTypeString()
    if cardType ~= "notype" then room:setPlayerMark(player, "@kl__qiangzhi-phase", cardType) end
  end,
}
local kl__qiangzhi_trigger = fk.CreateTriggerSkill {
  name = "#kl__qiangzhi_trigger",
  mute = true,
  events = { fk.CardUsing },
  can_trigger = function(self, event, target, player, data)
    return target == player and player.phase == Player.Play and player:getMark("@kl__qiangzhi-phase") ~= 0 and
        data.card:getTypeString() == player:getMark("@kl__qiangzhi-phase")
  end,
  on_cost = function(self, event, target, player, data)
    return player.room:askForSkillInvoke(player, "kl__qiangzhi", nil, "#kl__qiangzhi-invoke")
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    player:broadcastSkillInvoke("kl__qiangzhi", 2)
    room:notifySkillInvoked(player, "kl__qiangzhi", "drawcard")
    player:drawCards(1, "kl__qiangzhi")
  end,
}
local kl__xiantu = fk.CreateTriggerSkill {
  name = "kl__xiantu",
  mute = true,
  anim_type = "support",
  events = { fk.EventPhaseStart },
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and target.phase == Player.Play and not target.dead
  end,
  on_cost = function(self, event, target, player, data)
    return player.room:askForSkillInvoke(player, self.name, data, "#kl__xiantu-invoke::" .. target.id)
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    player:broadcastSkillInvoke(self.name, 1)
    room:notifySkillInvoked(player, self.name)
    room:doIndicate(player.id, { target.id })
    room:setPlayerMark(player, "kl__xiantu-phase", 1)
    player:drawCards(2, self.name)
    if player:isNude() or player.dead or player.room.current == player then return end
    local cards
    if #player:getCardIds { Player.Hand, Player.Equip } <= 2 then
      cards = player:getCardIds { Player.Hand, Player.Equip }
    else
      cards = room:askForCard(player, 2, 2, true, self.name, false, ".", "#kl__xiantu-give::" .. target.id)
    end
    room:moveCardTo(cards, Player.Hand, target, fk.ReasonGive, self.name, nil, false, player.id)
  end,
}
local kl__xiantu_trigger = fk.CreateTriggerSkill {
  name = "#kl__xiantu_trigger",
  mute = true,
  events = { fk.EventPhaseEnd },
  can_trigger = function(self, event, target, player, data)
    if target.phase == Player.Play and player:getMark("kl__xiantu-phase") > 0 then
      return #player.room.logic:getEventsOfScope(GameEvent.Death, 1, function(e)
        local death = e.data[1]
        return death.damage and death.damage.from == target
      end, Player.HistoryTurn) == 0
    end
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    local room = player.room
    player:broadcastSkillInvoke("kl__xiantu", 2)
    room:notifySkillInvoked(player, "kl__xiantu", "negative")
    room:loseHp(player, 1, "kl__xiantu")
  end,
}
kl__qiangzhi:addRelatedSkill(kl__qiangzhi_trigger)
kl__xiantu:addRelatedSkill(kl__xiantu_trigger)
zhangsong:addSkill(kl__qiangzhi)
zhangsong:addSkill(kl__xiantu)
Fk:loadTranslationTable {
  ["kl__zhangsong"] = "张松",
  ["#kl__zhangsong"] = "怀璧待凤仪",
  ["designer:kl__zhangsong"] = "官方&抗绿先锋",

  ["kl__qiangzhi"] = "强识",
  [":kl__qiangzhi"] = "出牌阶段开始时，你可展示一名其他角色的一张手牌，然后当你于此阶段内使用与此牌类别相同的牌时，你可摸一张牌。",
  ["kl__xiantu"] = "献图",
  [":kl__xiantu"] = "每名角色的出牌阶段开始时，你可摸两张牌，交给其两张牌。然后此阶段结束时，若其于此回合内未杀死过角色，你失去1点体力。",
  ["#kl__qiangzhi-choose"] = "强识：展示一名其他角色的一张手牌，此阶段内你使用类别相同的牌时，你可摸一张牌",
  ["#kl__qiangzhi-invoke"] = "强识：你可摸一张牌",
  ["@kl__qiangzhi-phase"] = "强识",
  ["#kl__xiantu-invoke"] = "献图：你可摸两张牌并交给 %dest 两张牌",
  ["#kl__xiantu-give"] = "献图：选择交给 %dest 的两张牌",

  ["$kl__qiangzhi1"] = "容我过目，即刻咏来。",
  ["$kl__qiangzhi2"] = "文书强识，才可博于运筹。",
  ["$kl__xiantu1"] = "将军莫虑，且看此图。",
  ["$kl__xiantu2"] = "我已诚心相献，君何踌躇不前？",
  ["~kl__zhangsong"] = "皇叔不听吾谏言，悔时晚矣！",
}

local guanyu = General(extension, "kl__guanyu", "shu", 4)
local kl__guanjue = fk.CreateTriggerSkill {
  name = "kl__guanjue",
  anim_type = "offensive",
  frequency = Skill.Compulsory,
  events = { fk.CardUsing, fk.CardResponding },
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and data.card.suit ~= Card.NoSuit and
        table.find(player.room:getOtherPlayers(player, false), function(p)
          return not table.contains(p:getTableMark("@kl__guanjue-turn"), data.card:getSuitString(true))
        end)
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    for _, p in ipairs(room:getOtherPlayers(player, false)) do
      room:doIndicate(player.id, { p.id })
      room:addTableMark(p, "@kl__guanjue-turn", data.card:getSuitString(true))
    end
  end,
}
local kl__guanjue_prohibit = fk.CreateProhibitSkill {
  name = "#kl__guanjue_prohibit",
  prohibit_use = function(self, player, card)
    return card and table.contains(player:getTableMark("@kl__guanjue-turn"), card:getSuitString(true))
  end,
  prohibit_response = function(self, player, card)
    return card and table.contains(player:getTableMark("@kl__guanjue-turn"), card:getSuitString(true))
  end,
}
local kl__wusheng = fk.CreateViewAsSkill {
  name = "kl__wusheng",
  -- prompt = "#juewu-viewas",
  anim_type = "offensive",
  pattern = ".",
  -- handly_pile = true,
  interaction = function(self, player)
    -- local cards = table.filter(U.getUniversalCards(player.room, "bt", false), function (id)
    --   return Fk:getCardById(id).is_damage_card
    -- end)
    local all_names = { "slash", "thunder__slash", "fire__slash", "duel", "fire_attack", "savage_assault",
      "archery_attack" }
    local names = U.getViewAsCardNames(player, "kl__wusheng", all_names, nil)
    if #names == 0 then return end
    return U.CardNameBox {
      choices = names,
      all_choices = all_names,
      -- default_choice = "kl__wusheng"
    }
  end,
  card_filter = function(self, to_select, selected)
    if #selected == 1 then return false end
    local card = Fk:getCardById(to_select)
    return card.color == Card.Red
  end,
  view_as = function(self, cards)
    if #cards ~= 1 or not self.interaction.data then return end
    local card = Fk:cloneCard(self.interaction.data)

    local n = Fk:translate(card.trueName, "zh_CN"):len()
    for _, id in ipairs(cards) do
      local subcard = Fk:getCardById(id)
      if not subcard then return end -- 检查子卡牌是否有效
      n = n - Fk:translate(Fk:getCardById(id).trueName, "zh_CN"):len()
    end
    if n > 0 then return end

    card.skillName = self.name
    if Fk:getCardById(cards[1]) then -- 检查 cards[1] 是否有效
      card:addSubcard(cards[1])
    else
      return
    end
    return card
  end,
  enabled_at_play = function(self, player)
    return true
  end,
  enabled_at_response = function(self, player)
    return true
  end,
}
guanyu:addSkill(kl__wusheng)
kl__guanjue:addRelatedSkill(kl__guanjue_prohibit)
guanyu:addSkill(kl__guanjue)
Fk:loadTranslationTable {
  ["kl__guanyu"] = "关羽",
  ["#kl__guanyu"] = "威震华夏",
  ["designer:kl__guanyu"] = "官方&抗绿先锋",

  ["kl__guanjue"] = "冠绝",
  [":kl__guanjue"] = "锁定技，当你使用或打出一张牌时，所有其他角色不能使用或打出此花色的牌直到回合结束。",
  ["@kl__guanjue-turn"] = "冠绝",
  ["kl__wusheng"] = "武圣",
  [":kl__wusheng"] = "你可将一张红色牌当一张牌名字数不大于X的伤害牌使用或打出（X为这张红色的牌名字数）",

  ["$kl__guanjue1"] = "河北诸将，以某观之，如土鸡瓦狗！",
  ["$kl__guanjue2"] = "小儿舞刀，不值一哂。",
  ["$kl__wusheng1"] = "关羽在此，尔等受死！",
  ["$kl__wusheng2"] = "看尔乃插标卖首！",
  ["~kl__guanyu"] = "皇叔厚恩，来世再报了…",
}

local zhaoyun = General:new(extension, "kl__zhaoyun", "shu", 4)
local kl__longdan = fk.CreateViewAsSkill {
  name = "kl__longdan",
  -- anim_type = "defensive",
  pattern = "slash,jink",
  prompt = "#kl__longdan",
  -- frequency = Skill.NotFrequent,

  interaction = function()
    local names = {}
    for _, name in ipairs({ "slash", "jink" }) do
      local card = Fk:cloneCard(name)
      if (Fk.currentResponsePattern == nil and Self:canUse(card)) or
          (Fk.currentResponsePattern and Exppattern:Parse(Fk.currentResponsePattern):match(card)) then
        table.insertIfNeed(names, card.name)
      end
    end
    if #names == 0 then return end
    return U.CardNameBox { choices = names }
  end,
  card_filter = Util.FalseFunc,
  view_as = function(self)
    if not self.interaction.data then return end
    local card = Fk:cloneCard(self.interaction.data)
    card.skillName = self.name
    return card
  end,

  before_use = function(self, player, use)
    local room = player.room
    local targets = table.map(table.filter(room.alive_players, function(p) return not p:isNude() end), Util.IdMapper)
    -- 选择目标角色
    local to = room:askForChoosePlayers(player, targets, 1, 1, "#kl__longdan-choose::", self.name, true)
    if #to == 0 then return end

    -- 选择并弃置牌
    local target = room:getPlayerById(to[1])
    local card = room:askForCardChosen(player, target, "he", self.name)
    if not card then return end

    -- 立即判断牌类型
    local realCard = Fk:getCardById(card)
    room:throwCard({ card }, self.name, target, player)

    -- 立即失去体力
    if (use.card.name == "slash" and realCard.trueName ~= "jink") or (use.card.name == "jink" and realCard.trueName ~= "slash") then
      room:loseHp(player, 1, self.name)
    end
  end,
  enabled_at_play = function(self, player)
    return table.find(Fk:currentRoom().alive_players, function(p) return not p:isNude() end)
  end,
  enabled_at_response = function(self, player, response)
    return table.find(Fk:currentRoom().alive_players, function(p) return not p:isNude() end)
  end,
}
local kl__juejing = fk.CreateTriggerSkill {
  name = "kl__juejing",
  anim_type = "drawcard",
  frequency = Skill.Compulsory,
  events = { fk.EnterDying, fk.AfterDying },
  on_use = function(self, event, target, player, data)
    player:drawCards(1, self.name)
  end,
}
zhaoyun:addSkill(kl__longdan)
zhaoyun:addSkill(kl__juejing)
Fk:loadTranslationTable {
  ["kl__zhaoyun"] = "赵云",
  ["#kl__zhaoyun"] = "北伐之柱",
  ["designer:kl__zhaoyun"] = "官方&抗绿先锋",

  ["kl__longdan"] = "龙胆",
  [":kl__longdan"] = "当你需要使用或打出【杀】/【闪】时，你可弃置一名角色的一张牌，若此牌不为【闪】/【杀】，你失去1点体力。然后视为你使用或打出之。",
  ["#kl__longdan"] = "是否发动「龙胆」视为使用【杀】或【闪】？",
  ["#kl__longdan-choose"] = "龙胆：选择一名角色弃置其一张牌视为使用一张【杀】或【闪】",
  ["kl__juejing"] = "绝境",
  [":kl__juejing"] = "锁定技，当你进入濒死状态时或你的濒死结算结束后，你摸一张牌。",

  ["$kl__juejing1"] = "背水一战，不胜便死！",
  ["$kl__juejing2"] = "置于死地，方能后生！",
  ["$kl__longdan1"] = "龙威虎胆，斩敌破阵！",
  ["$kl__longdan2"] = "进退自如，游刃有余！",
  ["~kl__zhaoyun"] = "你们谁…还敢再上……",
}

local shamoke = General(extension, "kl__shamoke", "shu", 4)
local jilis = fk.CreateTriggerSkill {
  name = "kl__jilis",
  anim_type = "drawcard",
  events = { fk.CardUsing, fk.CardResponding },
  can_trigger = function(self, event, target, player, data)
    if target == player and player:hasSkill(self) then
      local x, y = player:getAttackRange(), player:getMark("kl__jilis_times-turn")
      if x >= y then
        local room = player.room
        local logic = room.logic
        local end_id = player:getMark("kl__jilis_record-turn")
        local e = logic:getCurrentEvent()
        if end_id == 0 then
          local turn_event = e:findParent(GameEvent.Turn, false)
          if turn_event == nil then return false end
          end_id = turn_event.id
        end
        room:setPlayerMark(player, "kl__jilis_record-turn", logic.current_event_id)
        local events = logic.event_recorder[GameEvent.UseCard] or Util.DummyTable
        for i = #events, 1, -1 do
          e = events[i]
          if e.id <= end_id then break end
          local use = e.data[1]
          if use.from == player.id then
            y = y + 1
          end
        end
        events = logic.event_recorder[GameEvent.RespondCard] or Util.DummyTable
        for i = #events, 1, -1 do
          e = events[i]
          if e.id <= end_id then break end
          local use = e.data[1]
          if use.from == player.id then
            y = y + 1
          end
        end
        room:setPlayerMark(player, "kl__jilis_times-turn", y)
        return x == y
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    player:drawCards(player:getAttackRange())
  end,
}
shamoke:addSkill(jilis)
Fk:loadTranslationTable {
  ['kl__shamoke'] = '沙摩柯',
  ["#kl__shamoke"] = "五溪蛮王",
  ["designer:kl__shamoke"] = "官方",

  ["kl__jilis"] = "蒺藜",
  [":kl__jilis"] = "当你于一回合内使用或打出第X张牌时，你可以摸X张牌（X为你的攻击范围）。",

  ["$kl__jilis1"] = "蒺藜骨朵，威震慑敌！",
  ["$kl__jilis2"] = "看我一招，铁蒺藜骨朵！",
  ['~kl__shamoke'] = '五溪蛮夷，不可能输！',
}

local yijiy = General(extension, "kl__yijiy", "shu", 3)
local kl__jijie = fk.CreateTriggerSkill {
  name = "kl__jijie",
  events = { fk.TargetConfirmed },
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and
        not player:isKongcheng() and
        data.from ~= player.id and
        data.card:isCommonTrick() and
        player:canPindian(player.room:getPlayerById(data.from))
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local pindian = player:pindian({ room:getPlayerById(data.from) }, self.name)
    if pindian.results[data.from].winner == player then
      table.insertIfNeed(data.nullifiedTargets, player.id)
    end
  end,
}
local kl__jiyuan = fk.CreateTriggerSkill {
  name = "kl__jiyuan",
  events = { fk.EventPhaseStart },
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and target.phase == Player.Play and
        table.find(player.room.alive_players, function(p)
          return p:getHandcardNum() < 2
        end)
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local targets = table.map(table.filter(room.alive_players, function(p)
      return p:getHandcardNum() < 2
    end), Util.IdMapper)
    if #targets == 0 then return false end
    local to = room:askForChoosePlayers(player, targets, 1, 1, "#kl__jiyuan-choose", self.name, true)
    if #to > 0 then
      self.cost_data = to[1]
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local to = room:getPlayerById(self.cost_data)
    -- room:notifySkillInvoked(player, self.name, "support")
    -- player:broadcastSkillInvoke(self.name)
    to:drawCards(2, self.name)
    player.room:setPlayerMark(to, "@kl__jiyuan-phase", 1)
    room:handleAddLoseSkills(to, "#kl__jiyuan_distance")
    room.logic:getCurrentEvent():findParent(GameEvent.Phase):addCleaner(function()
      room:handleAddLoseSkills(to, "-#kl__jiyuan_distance")
    end)
  end,
}
local kl__jiyuan_distance = fk.CreateDistanceSkill {
  name = "#kl__jiyuan_distance",
  correct_func = function(self, from, to)
    if to:getMark("@kl__jiyuan-phase") ~= 0 and from ~= to then
      return 1
    end
  end,
}
kl__jiyuan:addRelatedSkill(kl__jiyuan_distance)
yijiy:addSkill(kl__jijie)
yijiy:addSkill(kl__jiyuan)
Fk:loadTranslationTable {
  ['kl__yijiy'] = '伊籍',
  ["#kl__yijiy"] = "礼仁同渡",
  ["designer:kl__yijiy"] = "抗绿先锋",

  ["kl__jijie"] = "机捷",
  [":kl__jijie"] = "当你成为普通锦囊牌的目标时，你可与使用者拼点。若你赢，此牌对你无效。",
  ["#kl__jijie"] = "机捷：与 %src 拼点，若你赢，此牌对你无效",
  ["kl__jiyuan"] = "急援",
  [":kl__jiyuan"] = "每名角色的出牌阶段开始时，你可令一名手牌数小于二的角色摸两张牌，本阶段除其以外角色至其的距离+1。",

  ["#kl__jiyuan-choose"] = "急援：选择一名手牌数小于二的角色",
  ["@kl__jiyuan-phase"] = "急援：距离+",
  ["#kl__jiyuan_distance"] = "急援",

  ["$kl__jijie1"] = "一拜一起，未足为劳。",
  ["$kl__jijie2"] = "识言观行，方能雍容风议。",
  ["$kl__jiyuan1"] = "公若辞，必遭蔡瑁之害矣。",
  ["$kl__jiyuan2"] = "形势危急，还请速行。",
  ["~kl__yijiy"] = "未能，救得刘公脱险……",
}

local zhugeliang = General(extension, "kl__zhugeliang", "shu", 3)
local kl__kongcheng = fk.CreateTriggerSkill {
  name = "kl__kongcheng",
  anim_type = "defensive",
  events = { fk.TargetConfirming },
  frequency = Skill.Compulsory,
  can_trigger = function(self, event, target, player, data)
    if not player:hasSkill(self) then return false end
    return target == player and (data.card.trueName == "slash" or data.card.name == "duel") and player:isKongcheng()
  end,
  on_use = function(self, event, target, player, data)
    AimGroup:cancelTarget(data, player.id)
    return true
  end
}
local kl__wentian = fk.CreateViewAsSkill {
  name = "kl__wentian",
  pattern = "fire_attack,nullification",
  interaction = function()
    local availableNames = { "fire_attack", "nullification" }
    local names = U.getViewAsCardNames(Self, "kl__wentian", availableNames)
    if #names > 0 then
      return U.CardNameBox { choices = names, all_choices = availableNames }
    end
  end,
  card_filter = Util.FalseFunc,
  view_as = function(self, cards)
    if #cards ~= 0 or not self.interaction.data then return end
    local card = Fk:cloneCard(self.interaction.data)
    card.skillName = self.name
    return card
  end,
  before_use = function(self, player, use)
    local room = player.room
    -- room:addPlayerMark(player, "kl__wentian-turn", 1)
    local judge = {
      who = player,
      reason = self.name,
      pattern = ".",
    }
    room:judge(judge)
    if (judge.card.color ~= Card.Red and use.card.name == "fire_attack") or (use.card.name == "nullification" and judge.card.color ~= Card.Black) then
      return ""
    end
  end,
  enabled_at_play = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryTurn) == 0
  end,
  enabled_at_response = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryTurn) == 0
  end,
}
zhugeliang:addSkill(kl__guanxing)
zhugeliang:addSkill(kl__kongcheng)
zhugeliang:addSkill(kl__wentian)
Fk:loadTranslationTable {
  ['kl__zhugeliang'] = '诸葛亮',
  ["#kl__zhugeliang"] = "卧龙",
  ["designer:kl__zhugeliang"] = "官方&抗绿先锋",

  ["kl__wentian"] = "问天",
  [":kl__wentian"] = "每回合限一次，当你需要使用【火攻】/【无懈可击】时，你可判定，若结果为：红/黑色，你视为使用之。",
  ["kl__kongcheng"] = "空城",
  [":kl__kongcheng"] = "锁定技，当你成为【杀】或【决斗】的目标时，若你没有手牌，取消之。",

  ["$kl__guanxing1"] = "观今夜天象，知天下大事。",
  ["$kl__guanxing2"] = "知天易，逆天难。",
  ["$kl__kongcheng1"] = "（悠扬的琴音）",
  ["$kl__kongcheng2"] = "（低沉的琴音）",
  ["$kl__wentian1"] = "祈星辰之力，佑我蜀汉！",
  ["$kl__wentian2"] = "伏望天恩，誓讨汉贼！",
  ["~kl__zhugeliang"] = "将星陨落，天命难违。",
}

local wuxian = General(extension, "kl__wuxian", "shu", 3, 3, General.Female)
local kl__yirong = fk.CreateActiveSkill {
  name = "kl__yirong",
  anim_type = "drawcard",
  target_num = 0,
  prompt = function()
    local x = Self:getHandcardNum() - Self:getMaxCards()
    if x > 0 then
      return "#kl__yirong-discard:::" .. tonumber(x)
    else
      return "#kl__yirong-draw:::" .. tonumber(-x)
    end
  end,
  card_num = function()
    return math.max(0, Self:getHandcardNum() - Self:getMaxCards())
  end,
  times = function(self)
    return Self.phase == Player.Play and 2 - Self:usedSkillTimes(self.name, Player.HistoryPhase) or -1
  end,
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) < 2 and
        player:getHandcardNum() ~= player:getMaxCards()
  end,
  card_filter = function(self, to_select, selected)
    return #selected < Self:getHandcardNum() - Self:getMaxCards() and
        Fk:currentRoom():getCardArea(to_select) == Card.PlayerHand and
        not Self:prohibitDiscard(Fk:getCardById(to_select))
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    if #effect.cards > 0 then
      room:addPlayerMark(player, MarkEnum.AddMaxCards, 1)
      room:throwCard(effect.cards, self.name, player, player)
    else
      local n = player:getMaxCards() - player:getHandcardNum()
      if n > 0 then
        room:addPlayerMark(player, MarkEnum.MinusMaxCards, 1)
        room:drawCards(player, n, self.name)
      end
    end
  end,
}
Fk:addQmlMark {
  name = "kl__guixiang",
  qml_path = "",
  how_to_show = function(name, value, p)
    local x = p:getMaxCards() + 1
    if x > 1 and x < 8 then
      return Fk:translate(Util.PhaseStrMapper(x))
    end
    return " "
  end,
}
local kl__guixiang = fk.CreateTriggerSkill {
  name = "kl__guixiang",
  anim_type = "special",
  frequency = Skill.Compulsory,
  events = { fk.EventPhaseChanging },
  can_trigger = function(self, event, target, player, data)
    if target == player and player:hasSkill(self) and
        data.to ~= Player.Play and data.to > Player.RoundStart and data.to < Player.NotActive then
      local room = player.room
      local turn_event = room.logic:getCurrentEvent():findParent(GameEvent.Turn, true)
      if turn_event == nil then return false end
      return #room.logic:getEventsByRule(GameEvent.Phase, player:getMaxCards(), function(e)
        return e.data[2] > Player.RoundStart and e.data[2] < Player.NotActive
      end, turn_event.id) + 1 == player:getMaxCards()
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:sendLog {
      type = "#PhaseChanged",
      from = player.id,
      arg = Util.PhaseStrMapper(data.to),
      arg2 = "phase_play",
    }
    data.to = Player.Play
  end,

  on_acquire = function(self, player)
    player.room:setPlayerMark(player, "@[kl__guixiang]", 1)
  end,
  on_lose = function(self, player)
    player.room:setPlayerMark(player, "@[kl__guixiang]", 0)
  end,
}
wuxian:addSkill(kl__yirong)
wuxian:addSkill(kl__guixiang)
Fk:loadTranslationTable {
  ["kl__wuxian"] = "吴苋",
  ["#kl__wuxian"] = "庄姝晏晏",
  ["designer:kl__wuxian"] = "官方",

  ["kl__yirong"] = "移荣",
  [":kl__yirong"] = "出牌阶段限两次，你可以将手牌摸/弃至手牌上限并令你手牌上限-1/+1。",
  ["kl__guixiang"] = "贵相",
  [":kl__guixiang"] = "锁定技，你回合内第X个阶段改为出牌阶段（X为你的手牌上限）。",

  ["#kl__yirong-discard"] = "发动 移荣，弃置%arg张手牌，令你的手牌上限+1",
  ["#kl__yirong-draw"] = "发动 移荣，摸%arg张牌，令你的手牌上限-1",
  ["#PhaseChanged"] = "%from 的 %arg 被改为了 %arg2",
  ["@[kl__guixiang]"] = "贵相",

  ["$kl__yirong1"] = "花开彼岸，繁荣不减当年。",
  ["$kl__yirong2"] = "移花接木，花容更胜从前。",
  ["$kl__guixiang1"] = "女相显贵，凤仪从龙。",
  ["$kl__guixiang2"] = "正官七杀，天生富贵。",
  ["~kl__wuxian"] = "玄德东征，何日归还？",
}

-- local kl__wuban = General(extension, "kl__wuban", "shu", 4, 4)
-- local kl__jintao = fk.CreateTriggerSkill {
--   anim_type = "drawcard",
--   name = "kl__jintao",
--   frequency = Skill.Compulsory,
--   events = { fk.EventPhaseStart },
--   can_trigger = function(self, event, target, player, data)
--     if player:hasSkill(self) and target == player and player.phase == Player.Finish then
--       local card = Fk:cloneCard("slash")
--       local card_skill = card.skill
--       local status_skills = Fk:currentRoom().status_skills[TargetModSkill] or Util.DummyTable
--       for _, skill in ipairs(status_skills) do
--         if skill:bypassTimesCheck(player, card_skill, Player.HistoryTurn, card, nil) then return false end
--       end
--       return player:usedCardTimes("slash", Player.HistoryTurn) >=
--       card_skill:getMaxUseTime(player, Player.HistoryTurn, card, nil)
--     end
--   end,
--   on_use = function(self, event, target, player, data)
--     local room = player.room
--     local mark = player:getMark("@kl__jintao-extraslash")
--     mark = mark + 1
--     room:setPlayerMark(player, "@kl__jintao-extraslash", mark)
--     player:drawCards(2, self.name)
--   end,
-- }

-- local kl__jintao_targetmod = fk.CreateTargetModSkill {
--   name = "#kl__jintao_targetmod",
--   residue_func = function(self, player, skill, scope)
--     if skill.trueName == "slash_skill" and player:getMark("@kl__jintao-extraslash") > 0 and scope == Player.HistoryTurn then
--       return player:getMark("@kl__jintao-extraslash")
--     end
--   end,
-- }

-- kl__jintao:addRelatedSkill(kl__jintao_targetmod)
-- kl__wuban:addSkill(kl__jintao)
-- Fk:loadTranslationTable {
--   ["kl__wuban"] = "吴班",
--   ["#kl__wuban"] = "笃进豪侠",
--   ["designer:kl__wuban"] = "汤圆&抗绿先锋",

--   ["kl__jintao"] = "进讨",
--   [":kl__jintao"] = "锁定技，结束阶段，若你本回合使用【杀】的次数不小于次数上限，你摸两张牌且此上限+1。",

--   ["@kl__jintao-extraslash"] = "进讨",
--   ["#kl__jintao_maxhand"] = "进讨",

--   ["$kl__jintao1"] = "一雪前耻，誓报前仇！",
--   ["$kl__jintao2"] = "量敌而进，直讨吴境！",
--   ["~kl__wuban"] = "恨……杀不尽吴狗！",
-- }

local huangyueying = General(extension, "kl__huangyueying", "shu", 3, 3, General.Female)
local kl__qicai = fk.CreateActiveSkill {
  name = "kl__qicai",
  prompt = "#kl__qicai",
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryTurn) < 1
  end,
  card_filter = function(self, to_select, selected)
    return #selected == 0 and Fk:getCardById(to_select).type == Card.TypeEquip
  end,
  target_filter = Util.FalseFunc,
  target_num = 0,
  min_card_num = 1,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local cards = effect.cards
    player:showCards(cards)
    local c = Fk:getCardById(cards[1])
    local allCardNames = {}
    -- 获取与 cards 类别相同的牌名
    local allCardIds = Fk:getAllCardIds()
    for _, id in ipairs(allCardIds) do
      local card = Fk:getCardById(id)
      if card.type == c.type and not table.contains(allCardNames, card.name) then
        table.insert(allCardNames, card.name)
      end
    end
    -- 移除延时锦囊牌
    local delayedTricks = { "indulgence", "supply_shortage", "lightning" }
    for _, name in ipairs(delayedTricks) do
      table.removeOne(allCardNames, name)
    end
    if #allCardNames == 0 then
      return
    end
    -- 选择牌名
    local cardName = room:askForChoice(player, allCardNames, "kl__qicai")
    local ex_card = room:printCard(cardName, c.suit, c.number)
    room:moveCardTo(c, Card.Void, nil, nil, self.name, nil, true, player.id)
    room:obtainCard(player, ex_card.id, true)
  end,
}
local kl__jizhi = fk.CreateTriggerSkill {
  name = "kl__jizhi",
  anim_type = "drawcard",
  events = { fk.CardUsing },
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and data.card:isCommonTrick() and
        (not data.card:isVirtual() or #data.card.subcards == 0)
  end,
  on_use = function(self, event, target, player, data)
    player:drawCards(1, self.name)
  end,
}
huangyueying:addSkill(kl__qicai)
huangyueying:addSkill(kl__jizhi)
Fk:loadTranslationTable {
  ["kl__huangyueying"] = "黄月英",
  ["#kl__huangyueying"] = "归隐的杰女",
  ["designer:kl__huangyueying"] = "官方&抗绿先锋",

  ["kl__jizhi"] = "集智",
  [":kl__jizhi"] = "当你使用非转化的普通锦囊牌时，你可摸一张牌。",
  ["kl__qicai"] = "奇才",
  [":kl__qicai"] = "出牌阶段限一次，你可将一张装备牌移出游戏并声明一种装备牌名，从游戏外获得一张该牌名的牌（花色点数相同）。",
  ["#kl__qicai"] = "声明一种与此牌类别相同的牌名，令此牌视为该牌名（延时锦囊除外）",

  ["~kl__huangyueying"] = "亮……",
  ["$kl__jizhi1"] = "哼哼～",
  ["$kl__jizhi2"] = "哼～",
  ["$kl__qicai1"] = "依我此计，便可破之。",
  ["$kl__qicai2"] = "以此无用之物，换得锦囊妙计。",
}
return extension
